package us.mooresr.aircraftscheduling.server;

import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.TimeZone;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import us.mooresr.aircraftscheduling.shared.model.Reservation;
import us.mooresr.aircraftscheduling.shared.model.User;
import us.mooresr.aircraftscheduling.shared.model.UserDetail;

import com.googlecode.objectify.Query;

public class MailNotifier {
	static  MailNotifier instance;
	
	private class Recipient {
		String emailAddress;
		String name;
		
		Recipient(String emailAddress, String name) {
			this.emailAddress = emailAddress;
			this.name = name;
		}
		
		public String getEmailAddress() {
			return emailAddress;
		}
		
		public String getName() {
			return name;
		}
	}
	
	private static final int CREATE = 0;
	private static final int DELETE = 1;
	
	private static final Logger log = Logger.getLogger(MailNotifier.class.getName());
	
	private MailNotifier() {
		log.setLevel(Level.ALL);
	}
	
	public static MailNotifier getInstance() {
		if (instance == null) {
			instance = new MailNotifier();
		}
		
		return instance;
	}
	
	public void sendNewReservationNotifications(Reservation reservation) {
		ArrayList<Recipient> recipients = getRecipients(CREATE);
		
		
		if (recipients.size() == 0) {
			return;
		}
		
		Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);
        

        String msgBody = "New reservation created for " + formattedReservation(reservation);

        try {
            Message msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress("admin@capitolflying.appspotmail.com", "Capitol Flying Admin"));
            for (Recipient r : recipients) {
            	msg.addRecipient(Message.RecipientType.TO,
                             new InternetAddress(r.getEmailAddress(), r.getName()));
            	log.info("Sending new reservations email to " + r.getEmailAddress());
            }
            msg.setSubject("Capitol Flying:  A reservation has been created");
            msg.setText(msgBody);
            Transport.send(msg);
    
        } catch (AddressException e) {
            // ...
        } catch (MessagingException e) {
            // ...
        } catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private String formattedReservation(Reservation reservation) {
		DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
		df.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
		
		String result = reservation.getReservingUserName() + " from " + 
			df.format(reservation.getStart()) + " to " +
			df.format(reservation.getEnd());
		
		return result;
	}

	public void sendDeletedReservationNotifications(Reservation reservation) {
		ArrayList<Recipient> recipients = getRecipients(DELETE);
		
		if (recipients.size() == 0) {
			return;
		}
		
		Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);

        String msgBody = "Reservation for " + formattedReservation(reservation) + " has been deleted.";

        try {
            Message msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress("admin@capitolflying.appspotmail.com", "Capitol Flying Admin"));
            for (Recipient r : recipients) {
            	msg.addRecipient(Message.RecipientType.TO,
                             new InternetAddress(r.getEmailAddress(), r.getName()));
            	log.info("Sending deleted reservations email to " + r.getEmailAddress());
            }
            msg.setSubject("Capitol Flying:  A reservation has been deleted");
            msg.setText(msgBody);
            Transport.send(msg);
    
        } catch (AddressException e) {
            // ...
        } catch (MessagingException e) {
            // ...
        } catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private ArrayList<Recipient> getRecipients(int type) {
		ArrayList<Recipient> recipients = new ArrayList<Recipient>();
		
		DAO dao = new DAO();
		
		ArrayList<User> userList = new ArrayList<User>();
		
		Query<User> q = dao.ofy().query(User.class);
		
		for (User u : q) {
			userList.add(u);
		}
		
		for (User u : userList) {
			UserDetail userDetail = dao.ofy().get(UserDetail.class, u.getUserId());
			if ((type == CREATE) && (userDetail.getNotifyOnNewReservation() != null) &&
					(userDetail.getNotifyOnNewReservation())) {
				recipients.add(new Recipient(userDetail.getEmail(), u.getName()));
			}
			if ((type == DELETE) && (userDetail.getNotifyOnDeletedReservation() != null) &&
					(userDetail.getNotifyOnDeletedReservation())) {
				recipients.add(new Recipient(userDetail.getEmail(), u.getName()));
			}
		}
		
		
		return recipients;
	}

}
